package com.itheima.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.entity.dto.DishDto;
import com.itheima.reggie.entity.dto.PageQueryDto;
import com.itheima.reggie.entity.dto.SetmealDto;
import com.itheima.reggie.mapper.SetmealMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import com.itheima.reggie.web.exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Name SetmealServiceImpl
 * @Author BaiXin
 * @Date 2022-11-03 9:44
 */
@Service
@Transactional
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
    @Autowired
    SetmealMapper setmealMapper;

    @Autowired
    SetmealDishService setmealDishService;

    @Autowired
    CategoryService categoryService;

    /**
     * 套餐添加
     *
     * @param setmealDto 套餐数据
     * @return
     */
    @Override
    public boolean saveWithDish(SetmealDto setmealDto) {
        //套餐名字重复校验
        checkSetmealName(setmealDto);

        //添加套餐基本信息
        int count = setmealMapper.insert(setmealDto);
        if (count > 0) {
            //得到setmealId
            Long setmealId = setmealDto.getId();
            //遍历菜品，添加setmealId
            List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
            for (SetmealDish setmealDish : setmealDishes) {
                setmealDish.setSetmealId(setmealId);
            }
            //添加套餐菜品信息
            boolean result = setmealDishService.saveBatch(setmealDishes);
            //正确返回
            return result;
        }
        return false;
    }

    /**
     * 分页查询 包含套餐分类名称
     *
     * @param pageQueryDto
     * @return
     */
    @Override
    public Page<SetmealDto> page(PageQueryDto pageQueryDto) {
        //分页构造
        Page<Setmeal> setmealPage = new Page<>(pageQueryDto.getPage(), pageQueryDto.getPageSize());

        //条件构造
        LambdaQueryWrapper<Setmeal> qw = Wrappers.lambdaQuery(Setmeal.class)
                .like(pageQueryDto.getName() != null, Setmeal::getName, pageQueryDto.getName())
                .orderByDesc(Setmeal::getUpdateTime);


        //分页查询
        this.page(setmealPage, qw);

        //查询所有套餐分类
        List<Category> categories = categoryService.findByType(2);

        //封装为Page<SetmealDto>
        Page<SetmealDto> dtoPage = new Page<>();

        //拷贝
        BeanUtils.copyProperties(setmealPage, dtoPage, "records");

        //records处理
        List<Setmeal> records = setmealPage.getRecords();
       /*
        ArrayList<SetmealDto> dtoArrayList = new ArrayList<>();
            for (Setmeal setmeal : records) {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(setmeal, setmealDto);
            for (Category category : categories) {
                if (category.getId().equals(setmeal.getCategoryId())) {
                    setmealDto.setCategoryName(category.getName());
                    break;
                }
            }
            dtoArrayList.add(setmealDto);

        }*/
        List<SetmealDto> dtoArrayList = records.stream().map(setmeal -> {
            SetmealDto setmealDto = new SetmealDto();
            BeanUtils.copyProperties(setmeal, setmealDto);

            for (Category category : categories) {
                if (category.getId().equals(setmeal.getCategoryId())) {
                    setmealDto.setCategoryName(category.getName());
                    break;
                }
            }
            return setmealDto;
        }).collect(Collectors.toList());
        dtoPage.setRecords(dtoArrayList);

        //返回
        return dtoPage;
    }


    /**
     * 根据ids批量删除
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIdsWithSetmealDish(List<Long> ids) {
        //根据ids查询当前选择套餐是否在起售中
        Integer countOn = setmealMapper.selectCount(
                Wrappers.lambdaQuery(Setmeal.class)
                        .in(Setmeal::getId, ids)
                        .eq(Setmeal::getStatus, 1));
        if (countOn > 0) {
            //不能删除
            throw new BusinessException("您所选择套餐包含售卖中套餐，请停售后删除。");
        }

        //删除中间表
        Wrapper<SetmealDish> qw = Wrappers.lambdaQuery(SetmealDish.class)
                .in(SetmealDish::getSetmealId, ids);
        boolean remove = setmealDishService.remove(qw);
        if (!remove) {
            throw new BusinessException("套餐菜品关联数据有误，删除失败,请重试");
        }

        //删除套餐表
        return setmealMapper.deleteBatchIds(ids) > 0;


    }

    /**
     * 批量修改状态
     *
     * @param status
     * @param ids
     * @return
     */
    @Override
    public boolean switchStatus(Integer status, Long[] ids) {
        // 遍历所有id，挨个更新
        // update dish set status  = #{status }  where id in (1,2,3,4)
        int count = setmealMapper.updateByIds(status, ids);
        return count > 0;
    }

    /**
     * 通用条件查询
     *
     * @param setmeal
     * @return
     */
    @Override
    public List<Setmeal> findByCondition(Setmeal setmeal) {
        //条件构造
        Wrapper<Setmeal> qw = Wrappers.lambdaQuery(Setmeal.class)
                .eq(setmeal.getId() != null, Setmeal::getId, setmeal.getId())
                .eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId())
                .eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus())
                .like(setmeal.getCode() != null, Setmeal::getCode, setmeal.getCode())
                .like(setmeal.getDescription() != null, Setmeal::getDescription, setmeal.getDescription())
                .like(setmeal.getName() != null, Setmeal::getName, setmeal.getName())
                .orderByDesc(Setmeal::getUpdateTime);

        //查询
        List<Setmeal> setmeals = this.list(qw);
        return setmeals;
    }

    /**
     * 检查套餐名称是否重复
     *
     * @param setmealDto
     * @return
     */
    private boolean checkSetmealName(SetmealDto setmealDto) {
        LambdaQueryWrapper<Setmeal> qw = Wrappers
                .lambdaQuery(Setmeal.class)
                .eq(Setmeal::getName, setmealDto.getName())
                .ne(setmealDto.getId() != null, Setmeal::getId, setmealDto.getId());
        Setmeal setmeal = setmealMapper.selectOne(qw);
        if (setmeal != null) {
            //已经存在
            throw new BusinessException("该套餐名称已经存在，请修改后重试");
        }
        return false;
    }
}
